package com.edu.exam.entity.exampaper.composition;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 组卷方案实体类
 * 所属模块：B-03 试卷管理模块
 * 对应数据库表：paper_scheme
 *
 * <p>组卷方案表用于存储自动组卷的方案配置信息，包含方案基本信息、配置参数、约束条件等。
 * 支持方案的完整生命周期管理，从创建、配置、激活到归档的全过程。</p>
 *
 * <p>核心功能：
 * - 方案配置管理：存储试卷总分、考试时长、难度分布等配置信息
 * - 约束条件设置：支持试题来源、时间范围、排除条件等约束配置
 * - 版本控制：支持方案的版本管理和历史记录
 * - 状态管理：支持草稿、激活、停用、归档等状态流转</p>
 *
 * <p>与B-03-02模块的GroupingScheme不同，本实体专注于自动组卷的技术方案配置，
 * 包含算法参数、性能要求等技术细节。</p>
 *
 * @author System
 * @version 1.0.0
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class PaperScheme {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 方案ID
     *
     * <p>组卷方案的唯一标识符，采用UUID格式生成。
     * 用于方案的唯一标识、任务关联和结果追踪。</p>
     */
    @Column(name = "scheme_id", nullable = false, length = 32, unique = true)
    private String schemeId;

    /**
     * 方案名称
     *
     * <p>组卷方案的显示名称，应简洁明了地描述方案的用途和特点。
     * 例如："Java程序设计期末考试组卷方案"、"计算机网络期中考试自动组卷方案"等。</p>
     */
    @Column(name = "name", nullable = false, length = 200)
    private String name;

    /**
     * 方案描述
     *
     * <p>组卷方案的详细描述，记录方案的用途、适用场景、特点等信息。
     * 可选字段，用于丰富方案的说明信息。</p>
     */
    @Column(name = "description", columnDefinition = "TEXT")
    private String description;

    /**
     * 试卷总分
     *
     * <p>生成试卷的总分值，默认为100分。
     * 可根据实际考试需求进行调整，如120分、150分等。</p>
     */
    @Column(name = "total_score", nullable = false, precision = 10, scale = 2)
    private Double totalScore = 100.0;

    /**
     * 考试时长（分钟）
     *
     * <p>考试的持续时间，单位为分钟。
     * 默认为120分钟（2小时），可根据课程特点和考试要求进行调整。</p>
     */
    @Column(name = "duration", nullable = false)
    private Integer duration = 120;

    /**
     * 方案状态
     *
     * <p>组卷方案的当前状态，支持完整的状态流转。
     * 状态包括：DRAFT（草稿）、ACTIVE（激活）、INACTIVE（停用）、ARCHIVED（归档）。</p>
     */
    @Column(name = "status", nullable = false, length = 20)
    private String status = "DRAFT";

    /**
     * 方案配置
     *
     * <p>JSON格式的方案详细配置信息，包含难度分布、题型配置、知识点要求等。
     * 支持灵活的配置扩展，满足不同组卷需求。</p>
     */
    @Column(name = "configuration", columnDefinition = "CLOB")
    private String configuration;

    /**
     * 约束条件
     *
     * <p>JSON格式的约束条件配置，包含试题排除规则、时间范围限制等。
     * 用于控制组卷时的试题选择范围和约束条件。</p>
     */
    @Column(name = "constraints", columnDefinition = "CLOB")
    private String constraints;

    /**
     * 创建者ID
     *
     * <p>创建方案的用户ID，关联系统用户表。
     * 用于记录方案的责任人和权限控制。</p>
     */
    @Column(name = "creator_id", nullable = false, length = 32)
    private String creatorId;

    /**
     * 版本号
     *
     * <p>方案的版本序号，用于版本控制和变更管理。
     * 初始值为1，每次重要更新时递增。</p>
     */
    @Column(name = "version", nullable = false)
    private Integer version = 1;

    /**
     * 是否删除
     *
     * <p>逻辑删除标识，false表示未删除，true表示已删除。
     * 使用软删除机制，保留历史数据用于审计和分析。</p>
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    // ===== 常量定义 =====

    /** 方案状态 - 草稿 */
    public static final String STATUS_DRAFT = "DRAFT";

    /** 方案状态 - 激活 */
    public static final String STATUS_ACTIVE = "ACTIVE";

    /** 方案状态 - 停用 */
    public static final String STATUS_INACTIVE = "INACTIVE";

    /** 方案状态 - 归档 */
    public static final String STATUS_ARCHIVED = "ARCHIVED";
}